#include "pwm_driver.h"
#include "gd32f4xx.h"
#include "systick.h"
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
//

// PD14 AF2 TIMER3_CH2
// void timer3_config(void)
// {
//     // 马达B8复用2
//     rcu_periph_clock_enable(RCU_GPIOB);
//     gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_8);
//     gpio_af_set(GPIOB, GPIO_AF_2, GPIO_PIN_8);

//     // 4倍频提升到168MHz
//     rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4);

//     // 定时器3设置
//     rcu_periph_clock_enable(RCU_TIMER3);
//     timer_deinit(TIMER3);

//     timer_parameter_struct initpara;
//     timer_struct_para_init(&initpara);

//     initpara.prescaler = 10000; // 16800Hz
//     initpara.period = 168 - 1;  // CAR 10ms
//     timer_init(TIMER3, &initpara);

//     // 定时器3输出通道配置  oc output channel
//     timer_oc_parameter_struct ocpara;
//     timer_channel_output_struct_para_init(&ocpara); // 设置默认值

//     // 设置极性
//     ocpara.outputstate = (uint16_t)TIMER_CCX_ENABLE;
//     // 设置输出通道 从复用功能看，PD14 仅选CH2
//     timer_channel_output_config(TIMER3, TIMER_CH_2, &ocpara);
//     // 设置输出模式
//     // TIMER_OC_MODE_PWM0 0->CCR之间输出高电平  CCR -> CAR输出低电平
//     // TIMER_OC_MODE_PWM1 0->CCR之间输出低电平  CCR -> CAR输出高电平
//     // 计数器 0 -> ++ -> CCR -> ++ -> CAR -> 0 ->...
//     timer_channel_output_mode_config(TIMER3, TIMER_CH_2, TIMER_OC_MODE_PWM0);
//     // 设置CCR
//     timer_channel_output_pulse_value_config(TIMER3, TIMER_CH_2, (168 - 1) * 0.01f);

//     timer_enable(TIMER3);
// }

// /* 传入duty范围是0~100 比如传入60，代表要求60%占空比 */
// void update_PWM(float duty)
// {
//     if (duty > 100)
//         duty = 100;
//     else if (duty < 0)
//         duty = 0;

//     float ccr = (168 - 1) * duty / 100.0f;

//     timer_channel_output_pulse_value_config(TIMER3, TIMER_CH_2, ccr);
// }

// void timer_channel_output_struct_para_init(timer_oc_parameter_struct *ocpara)
// {
//     /* initialize the channel output parameter struct member with the default value */
//     ocpara->outputstate  = (uint16_t)TIMER_CCX_DISABLE;
//     ocpara->outputnstate = TIMER_CCXN_DISABLE;
//     ocpara->ocpolarity   = TIMER_OC_POLARITY_HIGH;
//     ocpara->ocnpolarity  = TIMER_OCN_POLARITY_HIGH;
//     ocpara->ocidlestate  = TIMER_OC_IDLE_STATE_LOW;
//     ocpara->ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;
// }

void pwm_driver_config(void)
{
    // led灯
    //  LED_SW
    rcu_periph_clock_enable(RCU_GPIOC);
    gpio_mode_set(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_6);
    gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, GPIO_PIN_6);
    gpio_bit_reset(GPIOC, GPIO_PIN_6); // 低电平导通

    // GPIO PD14
    rcu_periph_clock_enable(RCU_GPIOD);
    gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_14);
    gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, GPIO_PIN_14);
    gpio_af_set(GPIOD, GPIO_AF_2, GPIO_PIN_14);

    // 配置timer3的外设时钟
    rcu_periph_clock_enable(RCU_TIMER3);

    // 复位timer3
    timer_deinit(TIMER3);

    // timer3默认主频42MHz,4倍频提升到168MHz
    rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4);

    // timer3初始化结构体
    timer_parameter_struct initpara;
    timer_struct_para_init(&initpara);

    // 根据需求配置参数
    // 预分配系数,分频系数,降频到168,000,000/10000 = 16800,也就是每秒16800次
    initpara.prescaler = 10000;
    // 自动重装载值,周期计数(最大值65535),每个周期计数16800
    initpara.period = 16800;
    //
    timer_init(TIMER3, &initpara);

    // 通道输出配置
    timer_oc_parameter_struct ocpara;               // 声明
    timer_channel_output_struct_para_init(&ocpara); // 初始化
    // 启用正极
    ocpara.outputstate = (uint16_t)TIMER_CCX_ENABLE;
    // 输出参数
    timer_channel_output_config(TIMER3, TIMER_CH_2, &ocpara);
    // 输出模式:pwm生成
    timer_channel_output_mode_config(TIMER3, TIMER_CH_2, TIMER_OC_MODE_PWM1);
    // 占空比
    timer_channel_output_pulse_value_config(TIMER3, TIMER_CH_2, 16800 * 0.01f);
    // 开启时钟
    timer_enable(TIMER3);
}

/**
 * 功率
 */
void pwm_driver_update(float duty)
{
    if (duty > 100)
    {
        duty = 100;
    }
    else if (duty < 0)
    {
        duty = 0;
    }
    // pulse / (PERIOD - 1) == duty / 100;
    uint32_t CCR = (16800 - 1) * duty / 100.0f;
    /* 设置通道输出脉冲值 （修改占空比） configure TIMER channel output pulse value */
    timer_channel_output_pulse_value_config(TIMER3, TIMER_CH_2, CCR);
}

void pwm_driver_test(void)
{
    systick_config();

    pwm_driver_config();
    uint8_t i;
    while (1)
    {
        for (i = 0; i <= 10; i++)
        {
            pwm_driver_update(i * 10);
            delay_1ms(300);
        }
        for (i = 9; i > 0; i--)
        {
            pwm_driver_update(i * 10);
            delay_1ms(300);
        }
    }
}